#include "bdd.h"
#include <stdarg.h>

unsigned int
td_select_base (char *se)
{
  racine *tmp;
  uint sid;
  td_err = 0;
  tmp = get_base (root_head, se);
  if (!tmp)
    {
      td_err = BASE_NOT_EXIST;
      return 0;
    }

  sid = add_session ();
  sess_tab[sid]->rootptr = tmp;
  sess_tab[sid]->subptr = tmp->base;
  sess_tab[sid]->rowptr = NULL;
  sess_tab[sid]->baseptr = tmp->base;
  return (sid);
}

td_row *
td_select_row (unsigned int si, char *se)
{
  row *rtmp;
  td_row *n;
  session *stmp;
  stmp = get_session (si);
  td_err = 0;
  if (!stmp)
    {
      td_err = INVALID_SESSION;
      return NULL;
    }

  if (!stmp->subptr)
    {
      td_err = INVALID_SUBBASE;
      return NULL;
    }

  rtmp = get_row (stmp->subptr->rows, se, stmp->rootptr->case_flag);
  if (rtmp)
    {
      stmp->rowptr = rtmp;
      n = make_row_td_row (rtmp);
      return (n);
    }
  td_err = ROW_NOT_EXIST;
  return NULL;
}


td_row *td_select_row_r (unsigned int si, int *nerr, char *srow, ...)
{
  va_list ap;
  row *rtmp = NULL;
  subbase *subtmp = NULL;
  td_row *n;
  char *se;
  session *stmp;
  
  stmp = get_session (si);
  td_err = 0;

  if (nerr)
	*nerr = 0;

  if (!stmp)
    {
      td_err = INVALID_SUBBASE;
      return NULL;
    }

  va_start (ap, srow);

  se =  va_arg (ap, char *); 
  while (se)
  {
	subtmp = get_subbase (stmp->subptr->enfant, se, stmp->rootptr->case_flag);
	if (subtmp)
	{
		stmp->subptr = subtmp;
		stmp->rowptr = NULL;
	}
	else
		break;
	
	se =  va_arg (ap, char *);
	if (nerr)
		(*nerr)++;
  }
  
  va_end (ap);
  
  if (subtmp)
  {
	rtmp = get_row (stmp->subptr->rows, srow, stmp->rootptr->case_flag);
	if (rtmp)
	{
		stmp->rowptr = rtmp;
		n = make_row_td_row (rtmp);
		return (n);
	}  
  }
  
  td_err = ROW_NOT_EXIST;
  return NULL;
}


td_row *
td_select_row_p (unsigned int si, char *buffer, char delim)
{
  td_row *n = NULL;
  int a, b;
  char **tab;

  td_err = 0;
  tab = str_to_tab (buffer, delim, &b);
  for (a = 0; a < b - 1; a++)
    {
      if (n)
	td_free_row (n);
      n = td_select_subbase (si, tab[a]);
      if (!n)
	break;
      free (tab[a]);
    }
  if (a == b - 1)
    {
      td_free_row (n);
      n = td_select_row (si, tab[a]);
    }

  for (; a < b; a++)
      free (tab[a]);
  free (tab);

  return (n);
}


td_row *
td_select_subbase (unsigned int si, char *se)
{
  subbase *subtmp;
  td_row *n;
  session *stmp;
  stmp = get_session (si);
  td_err = 0;
  if (!stmp)
    {
      td_err = INVALID_SUBBASE;
      return NULL;
    }

  subtmp = get_subbase (stmp->subptr->enfant, se, stmp->rootptr->case_flag);
  if (subtmp)
    {
      stmp->subptr = subtmp;
      stmp->rowptr = NULL;
      n = make_subbase_td_row (subtmp);
      return (n);
    }
  td_err = SUBBASE_NOT_EXIST;
  return NULL;
}


td_row *td_select_subbase_r (unsigned int si, int *nerr, ...)
{
  va_list ap;
  subbase *subtmp = NULL;
  td_row *n;
  char *se;
  session *stmp;
  
  stmp = get_session (si);
  td_err = 0;

  if (nerr)
	*nerr = 0;

  if (!stmp)
    {
      td_err = INVALID_SUBBASE;
      return NULL;
    }

  va_start (ap, nerr);

  se =  va_arg (ap, char *); 
  while (se)
  {
	subtmp = get_subbase (stmp->subptr->enfant, se, stmp->rootptr->case_flag);
	if (subtmp)
	{
		stmp->subptr = subtmp;
		stmp->rowptr = NULL;
	}
	else
		break;
	
	se =  va_arg (ap, char *);
	if (nerr)
		(*nerr)++;
  }
  
  va_end (ap);
  
  if (subtmp)
  {
  	n = make_subbase_td_row (subtmp);
	return (n);
  }
  
  td_err = SUBBASE_NOT_EXIST;
  return NULL;
}


td_row *
td_select_subbase_p (unsigned int si, char *buffer, char delim)
{
  td_row *n = NULL;
  int a, b;
  char **tab;

  td_err = 0;
  tab = str_to_tab (buffer, delim, &b);
  for (a = 0; a < b; a++)
    {
      if (n)
	td_free_row (n);
      n = td_select_subbase (si, tab[a]);
      if (!n)
	break;
      free (tab[a]);
    }

  for (; a < b; a++)
    free (tab[a]);
  free (tab);

  return (n);
}


td_row *
td_select_first_subbase (unsigned int si)
{
  td_row *n;
  session *stmp;
  subbase *popo;

  stmp = get_session (si);
  td_err = 0;
  if (!stmp)
    {
      td_err = INVALID_SESSION;
      return NULL;
    }

  if (!stmp->subptr)
    {
      td_err = INVALID_SUBBASE;
      return NULL;
    }
  popo = stmp->subptr;
  stmp->subptr = stmp->subptr->enfant;

  if (!stmp->subptr)
    {
      stmp->subptr = popo;
      td_err = SUBBASE_NOT_EXIST;
      return NULL;
    }
  else
    stmp->rowptr = NULL;

  n = make_subbase_td_row (stmp->subptr);
  return (n);
}


td_row *
td_select_next_subbase (unsigned int si)
{
  td_row *n;
  session *stmp;
  subbase *popo;

  stmp = get_session (si);
  td_err = 0;
  if (!stmp)
    {
      td_err = INVALID_SESSION;
      return NULL;
    }

  if (!stmp->subptr)
    {
      td_err = INVALID_SUBBASE;
      return NULL;
    }

  popo = stmp->subptr;
  stmp->subptr = stmp->subptr->next;

  stmp->rowptr = NULL;

  if (!stmp->subptr)
    {
      stmp->subptr = popo;
      td_err = SUBBASE_NOT_EXIST;
      return NULL;
    }
  else
    stmp->rowptr = NULL;

  n = make_subbase_td_row (stmp->subptr);
  return (n);
}

td_row *
td_select_parent_subbase (unsigned int si)
{
  td_row *n;
  session *stmp;
  stmp = get_session (si);
  td_err = 0;
  if (!stmp)
    {
      td_err = INVALID_SESSION;
      return NULL;
    }
  if (!stmp->subptr)
    {
      td_err = INVALID_SUBBASE;
      return NULL;
    }
  if (!stmp->subptr->parent)
    {
      td_err = SUBBASE_NOT_EXIST;
      return NULL;
    }

  stmp->subptr = stmp->subptr->parent;
  stmp->rowptr = NULL;

  n = make_subbase_td_row (stmp->subptr);
  return (n);
}

td_row *
td_select_next_row (unsigned int si)
{
  td_row *n;
  session *stmp;
  stmp = get_session (si);
  td_err = 0;
  if (!stmp)
    {
      td_err = INVALID_SESSION;
      return NULL;
    }
  if (!stmp->subptr)
    {
      td_err = INVALID_SUBBASE;
      return NULL;
    }

  if (stmp->rowptr)
    stmp->rowptr = stmp->rowptr->next;
  else
    stmp->rowptr = stmp->subptr->rows;

  if (!stmp->rowptr)
    {
      td_err = ROW_NOT_EXIST;
      return NULL;
    }

  n = make_row_td_row (stmp->rowptr);
  return (n);
}

td_row *
td_select_first_row (unsigned int si)
{
  td_row *n;
  session *stmp;
  stmp = get_session (si);
  td_err = 0;
  if (!stmp)
    {
      td_err = INVALID_SESSION;
      return NULL;
    }
  if (!stmp->subptr)
    {
      td_err = INVALID_SUBBASE;
      return NULL;
    }

  stmp->rowptr = stmp->subptr->rows;

  if (!stmp->rowptr)
    {
      td_err = ROW_NOT_EXIST;
      return NULL;
    }

  n = make_row_td_row (stmp->rowptr);
  return (n);
}
